import java.lang.reflect.Constructor;


/**
 * http://stackoverflow.com/questions/936684/getting-the-class-name-from-a-static-method-in-java
 * http://stackoverflow.com/questions/601395/getclass-and-static-methods-what-is-the-best-practice
 * 
 * Good article on Reflection
 * http://java.sun.com/developer/technicalArticles/ALT/Reflection/
 * 
 * http://en.wikibooks.org/wiki/Java_Programming/Reflection/Dynamic_Invocation
 */
public class ReflectionTest
{
    public static void main(String[] args)
    {
        System.out.println("ChildOne.getStaticClass : " + ChildOne.getStaticClass().getName());
        System.out.println("ChildTwo.getStaticClass : " + ChildTwo.getStaticClass().getName());
        System.out.println("ChildOne.create : " + ChildOne.create());
        System.out.println("ChildTwo.create : " + ChildTwo.create());
    }
    
}

class Parent
{
    static public Parent create( Class klass ) {
        //String className = getStaticClass().getName();
        String className = klass.toString();
        System.out.println(className);
        try {
            Constructor constructor = klass.getConstructor(null);
            
            return (Parent) constructor.newInstance();
        } catch (Exception e) {
            e.printStackTrace();
            return null;
        }
    }
    
    static public Class<Parent> getStaticClass() { return reallyGetStaticClass(); }
    
    static public Class<Parent> reallyGetStaticClass() {
        // * METHOD ONE
        // return new Object() { }.getClass().getEnclosingClass().getName();  // => Parent
        
        // * METHOD TWO
        Throwable t = new Throwable();
        t.fillInStackTrace();
        StackTraceElement[] elements = t.getStackTrace(); // for debugging
        StackTraceElement   element  = t.getStackTrace()[1];
        
        Class klass = null;
//        System.out.println(element.getClassName());
        try {
            klass = Class.forName(element.getClassName());
        } catch (ClassNotFoundException e) {
            e.printStackTrace();
        }
        
        
        // METHOD THREE
        // A slight better approach is Thread.currentThread().getStackTrace().
        
        return klass;
    }
}

class ChildOne extends Parent
{
    static private Class<ChildOne> __klass = ChildOne.class;
    static private Class<Parent> __staticClass;
    
    static public ChildOne create() {
        return (ChildOne) Parent.create( __klass );
    }
    
    static public Class<Parent> getStaticClass() {
        if (__staticClass == null)
            __staticClass = reallyGetStaticClass();
        return __staticClass;
    }
    
    public ChildOne() {
    }
}

class ChildTwo extends Parent
{
    static private Class<ChildTwo> __klass = ChildTwo.class;
    static private Class<Parent> __staticClass;

    static public ChildTwo create() {
        return (ChildTwo) Parent.create( __klass );
    }
    
    static public Class<Parent> getStaticClass() {
        if (__staticClass == null)
            __staticClass = reallyGetStaticClass();
        return __staticClass;
    }
    
    public ChildTwo() {
    }
}